package cn.t.modules.scheduler.core.config;

import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.JdbcType;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;

/**
 * 数据源配置类(本地库)
 * @author TMQ
 * @date 2022年5月18日 17点03分
 */
@Configuration
@MapperScan(basePackages = {"cn.t.modules.scheduler.core.schedule.repository.mapper"}, sqlSessionTemplateRef = MybatisLocalConfig.SQL_SESSION_TEMPLATE)
public class MybatisLocalConfig {

    public static final String TX_MANAGER = "txManager1";

    /**
     * sqlSession template
     */
    public static final String SQL_SESSION_TEMPLATE = "scheduleSqlSessionTemplate1";

    /**
     * 数据源的连接属性
     * @return 数据源的连接属性
     */
    @Bean("prop1")
    @ConfigurationProperties(prefix = "schedule.datasource")
    @Primary
    public DataSourceProperties dataSourceProperties() {
        return new DataSourceProperties();
    }

    /**
     * 数据源以及连接池
     * @return 数据源以及连接池
     */
    @Bean("ds1")
    @ConfigurationProperties(prefix = "schedule.datasource.hikari")
    @Primary
    public DataSource dataSource() {
        return this.dataSourceProperties().initializeDataSourceBuilder().build();
    }

    /**
     * 事务管理器
     * @return 事务管理器
     */
    @Bean(name = MybatisLocalConfig.TX_MANAGER)
    @Primary
    public PlatformTransactionManager txManager() {
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(this.dataSource());
        // 事务180秒超时
        transactionManager.setDefaultTimeout(180);
        return transactionManager;
    }

    /**
     * sqlSession工厂
     * @return sqlSession工厂
     * @throws Exception xml位置未找到
     */
    @Bean(name = "scheduleFactory1")
    @Primary
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
        sqlSessionFactory.setDataSource(this.dataSource());
        sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().
                getResources("classpath*:mapper/**/*.xml"));
        MybatisConfiguration configuration = new MybatisConfiguration();
        // 插入或者更新数据时,如果对象字段为null，则插入/更新为null，不设此属性需要在xml中指定JdbcType
        configuration.setJdbcTypeForNull(JdbcType.NULL);
        // 打印sql log
        //configuration.setLogImpl(org.apache.ibatis.logging.stdout.StdOutImpl.class);
        // 开启驼峰映射
        configuration.setMapUnderscoreToCamelCase(true);
        sqlSessionFactory.setConfiguration(configuration);
        return sqlSessionFactory.getObject();
    }

    /**
     * sqlSession
     * @return sqlSession
     */
    @Bean(name = SQL_SESSION_TEMPLATE)
    @Primary
    public SqlSessionTemplate ds1SqlSessionTemplate() throws Exception {
        return new SqlSessionTemplate(this.sqlSessionFactory());
    }
}
